<template>
  <!-- 普通输入框 -->
  <el-input
    v-if="config.type === 'input'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  >
    <template v-if="config.params?.suffixIcon" #suffix>
      <el-icon class="suffix-icon" @click="handleSuffixIconClick" :size="16">
        <component :is="config.params.suffixIcon" />
      </el-icon>
    </template>
  </el-input>

  <!-- 文本域 -->
  <el-input
    v-else-if="config.type === 'textarea'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 密码输入框 -->
  <el-input
    v-else-if="config.type === 'password'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 数字输入框 -->
  <el-input-number
    v-else-if="config.type === 'number'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 选择器 -->
  <el-select
    v-else-if="config.type === 'select'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  >
    <!-- <el-option
      v-if="!config.required && !config.params?.multiple"
      label="请选择"
      :value="null"
    /> -->
    <el-option
      v-for="option in getOptions()"
      :key="option.value"
      :label="option.label"
      :value="option.value"
      :disabled="option.disabled"
    />
  </el-select>

  <!-- 单选框组 -->
  <el-radio-group
    v-else-if="config.type === 'radio'"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  >
    <el-radio
      v-for="option in getOptions()"
      :key="option.value"
      :label="option.value"
      :disabled="option.disabled"
    >
      {{ option.label }}
    </el-radio>
  </el-radio-group>

  <!-- 多选框组 -->
  <el-checkbox-group
    v-else-if="config.type === 'checkbox'"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  >
    <el-checkbox
      v-for="option in getOptions()"
      :key="option.value"
      :label="option.value"
      :disabled="option.disabled"
    >
      {{ option.label }}
    </el-checkbox>
  </el-checkbox-group>

  <!-- 开关 -->
  <el-switch
    v-else-if="config.type === 'switch'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 日期选择器 -->
  <el-date-picker
    v-else-if="config.type === 'date'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 日期时间选择器 -->
  <el-date-picker
    v-else-if="config.type === 'datetime'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 时间选择器 -->
  <el-time-picker
    v-else-if="config.type === 'time'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 级联选择器 -->
  <el-cascader
    v-else-if="config.type === 'cascader'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 滑块 -->
  <el-slider
    v-else-if="config.type === 'slider'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 评分 -->
  <el-rate
    v-else-if="config.type === 'rate'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 颜色选择器 -->
  <el-color-picker
    v-else-if="config.type === 'color-picker'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />

  <!-- 上传组件 -->
  <el-upload
    v-else-if="config.type === 'upload'"
    v-bind="getComponentProps()"
    @change="handleChange"
  >
    <el-button size="small" type="primary">点击上传</el-button>
    <template #tip>
      <div class="el-upload__tip">
        {{ config.params?.uploadTip || "只能上传jpg/png文件，且不超过500kb" }}
      </div>
    </template>
  </el-upload>

  <!-- 自动完成组件 -->
  <el-autocomplete
    v-else-if="config.type === 'autocomplete'"
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
    @select="handleSelect"
  >
    <template #default="{ item }">
      <div class="autocomplete-item">
        <span class="keyword">{{ item.keyword }}</span>
        <span class="meaning">{{ item.meaning }}</span>
      </div>
    </template>
    <template v-if="config.params?.suffixIcon" #suffix>
      <el-icon
        class="suffix-icon"
        @click.stop="handleSuffixIconClick"
        :size="16"
      >
        <component :is="config.params.suffixIcon" />
      </el-icon>
    </template>
  </el-autocomplete>

  <!-- 按钮组件 -->
  <el-button
    v-else-if="config.type === 'button'"
    v-bind="getComponentProps()"
    @click="handleButtonClick"
  >
    {{ config.params?.text || config.name }}
  </el-button>

  <!-- 默认输入框 -->
  <el-input
    v-else
    v-bind="getComponentProps()"
    :model-value="modelValue"
    @update:model-value="handleUpdate"
    @change="handleChange"
  />
</template>

<script setup lang="ts">
import type { FormItemConfig } from "./types";

defineOptions({
  name: "DynamicFormItem",
});

interface Props {
  config: FormItemConfig;
  modelValue: any;
}

const props = defineProps<Props>();

const emit = defineEmits<{
  "update:modelValue": [value: any];
  change: [value: any];
}>();

// 获取选项数据，优先使用 config.options，如果没有则使用 config.params.options
const getOptions = () => {
  return props.config.options || props.config.params?.options || [];
};

// 获取组件属性
const getComponentProps = () => {
  // 根据不同类型设置不同的默认占位符
  const getDefaultPlaceholder = (type: string, name: string) => {
    switch (type) {
      case "select":
      case "cascader":
        return `请选择${name}`;
      case "date":
        return "请选择日期";
      case "datetime":
        return "请选择日期时间";
      case "time":
        return "请选择时间";
      default:
        return `请输入${name}`;
    }
  };

  const baseProps: Record<string, any> = {
    placeholder:
      props.config.placeholder ||
      getDefaultPlaceholder(props.config.type, props.config.name),
    disabled: props.config.disabled,
    clearable: props.config.params?.clearable ?? true,
    size: props.config.params?.size,
    style: props.config.params?.style,
  };

  // 根据不同类型设置特定属性
  switch (props.config.type) {
    case "textarea":
      return {
        ...baseProps,
        type: "textarea",
        rows: props.config.params?.rows || 3,
        maxlength: props.config.params?.maxLength,
        "show-word-limit": props.config.params?.showWordLimit,
        resize: props.config.params?.resize || "vertical",
      };

    case "password":
      return {
        ...baseProps,
        type: "password",
        "show-password": props.config.params?.showPassword ?? true,
      };

    case "number":
      return {
        ...baseProps,
        min: props.config.params?.min,
        max: props.config.params?.max,
        step: props.config.params?.step || 1,
        precision: props.config.params?.precision,
        "controls-position": props.config.params?.controlsPosition || "right",
      };

    case "select":
      return {
        ...baseProps,
        multiple: props.config.params?.multiple,
        filterable: props.config.params?.filterable,
        remote: props.config.params?.remote,
        "remote-method": props.config.params?.remoteMethod,
        "collapse-tags": props.config.params?.collapseTags,
        "collapse-tags-tooltip": props.config.params?.collapseTagsTooltip,
      };

    case "date":
      return {
        ...baseProps,
        type: props.config.params?.type || "date", // 支持通过 params.type 设置为 daterange
        format: props.config.params?.format || "YYYY-MM-DD",
        "value-format": props.config.params?.valueFormat || "YYYY-MM-DD",
        "range-separator": props.config.params?.rangeSeparator || "至",
        "start-placeholder": props.config.params?.startPlaceholder || "开始日期",
        "end-placeholder": props.config.params?.endPlaceholder || "结束日期",
      };

    case "datetime":
      return {
        ...baseProps,
        type: "datetime",
        format: props.config.params?.format || "YYYY-MM-DD HH:mm:ss",
        "value-format":
          props.config.params?.valueFormat || "YYYY-MM-DD HH:mm:ss",
      };

    case "time":
      return {
        ...baseProps,
        format: props.config.params?.format || "HH:mm:ss",
        "value-format": props.config.params?.valueFormat || "HH:mm:ss",
      };

    case "upload":
      return {
        action: props.config.params?.action || "#",
        accept: props.config.params?.accept,
        multiple: props.config.params?.multiple,
        limit: props.config.params?.limit,
        "auto-upload": props.config.params?.autoUpload ?? true,
        "show-file-list": props.config.params?.showFileList ?? true,
        drag: props.config.params?.drag,
        "list-type": props.config.params?.listType || "text",
      };

    case "cascader":
      return {
        ...baseProps,
        options: getOptions(),
        props: props.config.params?.cascaderProps || {
          checkStrictly: false,
          emitPath: false,
        },
        filterable: props.config.params?.filterable,
        "collapse-tags": props.config.params?.collapseTags,
      };

    case "switch":
      return {
        "active-text": props.config.params?.activeText,
        "inactive-text": props.config.params?.inactiveText,
        "active-value": props.config.params?.activeValue ?? true,
        "inactive-value": props.config.params?.inactiveValue ?? false,
        "inline-prompt": props.config.params?.inlinePrompt,
      };

    case "slider":
      return {
        ...baseProps,
        min: props.config.params?.min || 0,
        max: props.config.params?.max || 100,
        step: props.config.params?.step || 1,
        "show-stops": props.config.params?.showStops,
        "show-tooltip": props.config.params?.showTooltip ?? true,
        range: props.config.params?.range,
        vertical: props.config.params?.vertical,
      };

    case "rate":
      return {
        max: props.config.params?.max || 5,
        "allow-half": props.config.params?.allowHalf,
        "low-threshold": props.config.params?.lowThreshold || 2,
        "high-threshold": props.config.params?.highThreshold || 4,
        colors: props.config.params?.colors,
        "void-color": props.config.params?.voidColor,
        "disabled-void-color": props.config.params?.disabledVoidColor,
        "show-text": props.config.params?.showText,
        "show-score": props.config.params?.showScore,
        "text-color": props.config.params?.textColor,
        texts: props.config.params?.texts,
      };

    case "color-picker":
      return {
        "show-alpha": props.config.params?.showAlpha,
        "color-format": props.config.params?.colorFormat,
        predefine: props.config.params?.predefine,
      };

    case "autocomplete":
      return {
        ...baseProps,
        "fetch-suggestions": props.config.params?.fetchSuggestions,
        "trigger-on-focus": props.config.params?.triggerOnFocus ?? false,
        debounce: props.config.params?.debounce ?? 300,
        "highlight-first-item":
          props.config.params?.highlightFirstItem ?? false,
        "select-when-unmatched":
          props.config.params?.selectWhenUnmatched ?? false,
        "hide-loading": props.config.params?.hideLoading ?? false,
        "popper-class": props.config.params?.popperClass,
        placement: props.config.params?.placement || "bottom-start",
      };

    case "button":
      return {
        type: props.config.params?.type || "default",
        size: props.config.params?.size || "default",
        plain: props.config.params?.plain,
        round: props.config.params?.round,
        circle: props.config.params?.circle,
        loading: props.config.params?.loading,
        disabled: props.config.disabled || props.config.params?.disabled,
        icon: props.config.params?.icon,
        autofocus: props.config.params?.autofocus,
        "native-type": props.config.params?.nativeType || "button",
      };

    default:
      return baseProps;
  }
};

// 处理值更新
const handleUpdate = (value: any) => {
  emit("update:modelValue", value);
};

// 处理change事件
const handleChange = (value: any) => {
  emit("change", value);
};

// 处理按钮点击事件
const handleButtonClick = () => {
  if (props.config.params?.onClick) {
    props.config.params.onClick();
  }
};

// 处理suffix图标点击事件
const handleSuffixIconClick = () => {
  if (props.config.params?.suffixIconClick) {
    props.config.params.suffixIconClick();
  }
};

// 处理自动完成选择事件
const handleSelect = (item: any) => {
  if (props.config.params?.onSelect) {
    const result = props.config.params.onSelect(item);
    if (result !== undefined) {
      emit("update:modelValue", result);
    }
  }
};
</script>

<style scoped>
.suffix-icon {
  cursor: pointer;
  color: #909399;
  transition: color 0.3s;
}

.suffix-icon:hover {
  color: #409eff;
}
</style>
